package WebFinder

import (
	"gitee.com/fierce_wolf/go-web-crawler/WebCrawler"
	"regexp"
	"unicode"
)

type ChineseName struct {
	List []*WebCrawler.WebElement // 家庭、办公地址的相关元素，其中text字段被识别为地址
}

func (e *ChineseName) GetList() []*WebCrawler.WebElement {
	return e.List
}

func (e *ChineseName) Find(els []*WebCrawler.WebElement) []*WebCrawler.WebElement {
	e.List = make([]*WebCrawler.WebElement, 0)

	// 查找长度是2-6个字符的元素
	reg := regexp.MustCompile(`^[\p{Han}]{2,6}$`)
	els = WebCrawler.Site.FindElements(els, WebCrawler.Filter{
		Mode:  WebCrawler.ModeRegexp,
		Param: reg,
	})

	// 组合词，"姓名：张三"
	combinWord := `^\s*([\p{Han}]+)[\s:：=]+([\p{Han}]+)\s*$`
	combinReg := regexp.MustCompile(combinWord)

	// 单姓，"张三"
	singleSurname := `^(王|李|张|刘|陈|杨|黄|胡|赵|周|吴|徐|孙|郭|马|朱|林|高|宋|何|罗|梁|郑|曹|谢|韩|唐|于|董|彭|姚|冯|夏|邓|许|傅|袁|曾|贾|吕|苏|卢|程|蔡|肖|余|魏|薛|叶|阎|丁|潘|杜|戴|蒋|钟|汪|毛|任|田|范|方|石|沈|谭|廖|姜|熊|金|陆|郝|江|白|崔|康|邹|邱|秦|孔|史|顾|侯|邵|孟|洪|万|段|莫|钱|龚|尹|黎|常|武|乔|贺|赖|汤|文|易|庞|樊|兰|殷|施|陶|龙|翟|安|颜|倪|严|牛|温|芦|季|俞|章|鲁|葛|伍|韦|申|尤|毕|聂|丛|焦|向|柳|邢|路|岳|齐|沿|梅|莫|庄|辛|管|祝|左|涂|谷|祁|时|舒|耿|牟|卜|路|詹|关|苗|凌|费|纪|靳|盛|童|欧|甄|项|曲|成|游|阳|裴|席|卫|查|屈|鲍|位|覃|霍|翁|隋|植|甘|景|薄|单|包|司|柏|宁|柯|阮|桂|闵|解|强|柴|华|车|冉|房|边|辜|吉|饶|刁|瞿|戚|丘|古|米|池|滕|晋|苑|邬|臧|畅|宫|来|嵺|苟|全|褚|廉|简|娄|盖|符|奚|木|穆|党|燕|郎|邸|冀|谈|姬|屠|连|郜|晏|栾|郁|商|蒙|计|喻|揭|窦|迟|宇|敖|糜|鄢|冷|卓|花|仇|艾|蓝|都|巩|稽|井|练|仲|乐|虞|卞|封|竺|冼|原|官|衣|楚|佟|栗|匡|宗|应|台|巫|鞠|僧|桑|荆|谌|银|扬|明|沙|薄|伏|岑|习|胥|保|和|蔺)`
	singleReg := regexp.MustCompile(singleSurname)

	// 复姓，"司马相如"
	doubleSurname := `^(欧阳|司马|上官|夏侯|诸葛|东方|皇甫|尉迟|公孙|轩辕|令狐|宇文|长孙|慕容|司徒|司空)`
	doubleReg := regexp.MustCompile(doubleSurname)

	originals := make([]*WebCrawler.WebElement, 0)
	for _, el := range els {
		name, ok := e.getChineseName(el, combinReg, singleReg, doubleReg)
		if !ok {
			continue
		}

		originals = append(originals, el)

		clone := el.Clone()
		clone.Text = name
		e.List = append(e.List, clone)
	}

	return originals
}

func (e *ChineseName) getChineseName(el *WebCrawler.WebElement, combinReg, singleReg, doubleReg *regexp.Regexp) (string, bool) {
	hasMatch, result := e.extractAfterSpaceOrColon(el.Text, combinReg)
	if hasMatch {
		if e.isChineseName(result, singleReg, doubleReg) {
			return result, true
		}
	} else {
		if e.isChineseName(result, singleReg, doubleReg) {
			return result, true
		}
	}

	return result, false
}

func (e *ChineseName) countChineseChars(s string) int {
	count := 0
	for _, r := range s {
		if unicode.Is(unicode.Han, r) {
			count++
		}
	}
	return count
}

func (e *ChineseName) isChineseName(result string, singleReg *regexp.Regexp, doubleReg *regexp.Regexp) bool {
	// 场景1：这是连续的汉字，那么要符合2到4个汉字的姓名长度规则
	count := e.countChineseChars(result)

	// 检测：汉字名：2到4个汉
	if count < 2 || count > 4 {
		return false
	}

	//  2个的单姓
	if count == 2 && len(singleReg.FindAllString(result, -1)) > 0 {
		return true
	}
	//  3个的单姓和复姓
	if count == 3 && (len(singleReg.FindAllString(result, -1)) > 0 || len(doubleReg.FindAllString(result, -1)) > 0) {
		return true
	}
	//  4个的复姓
	if count == 4 && len(doubleReg.FindAllString(result, -1)) > 0 {
		return true
	}

	return false
}

func (e *ChineseName) extractAfterSpaceOrColon(input string, combinReg *regexp.Regexp) (bool, string) {
	matches := combinReg.FindStringSubmatch(input)
	if len(matches) > 0 {
		return true, matches[len(matches)-1]
	}

	return false, input
}
